/*******************************************************************************
  * 文件：Flash.c
  * 作者：zyz
  * 版本：v1.0.0
  * 日期：2017-05-16
  * 说明：flash代码
*******************************************************************************/
/* 头文件 *********************************************************************/
#include "Flash.h"
#include "Hardware.h"
#include "fsl.h"
#include "fsl_types.h"

/* 宏定义 *********************************************************************/
/* 类型定义 *******************************************************************/
/* 变量定义 *******************************************************************/
/* 函数声明 *******************************************************************/
/* 函数定义 *******************************************************************/
/*******************************************************************************
  * 函数名：Flash_Init
  * 功  能：初始化
  * 参  数：无
  * 返回值：无
  * 说  明：无
*******************************************************************************/
void Flash_Init(void)
{
    fsl_u08 xStatus;
    fsl_descriptor_t xDescriptorStr;

    // 设置参数
    xDescriptorStr.fsl_flash_voltage_u08     = 0x00;  // 电压模式: 全速模式
    xDescriptorStr.fsl_frequency_u08         = 0x20;  // 时钟频率: 32MHz
    xDescriptorStr.fsl_auto_status_check_u08 = 0x00;  // 状态检查模式: 用户模式

    // 初始化参数
    xStatus = FSL_Init(&xDescriptorStr);
    if(xStatus != FSL_OK)
    {
        while(1);
    }

    // 初始化环境
    FSL_Open();
    FSL_PrepareFunctions();
}

/*******************************************************************************
  * 函数名：Flash_BlankCheck
  * 功  能：检查块
  * 参  数：U16 u16BlockNum - 块号
  * 返回值：结果
  * 说  明：无
*******************************************************************************/
#pragma location="FSL_RCD"
Bool Flash_BlankCheck(U16 u16BlockNum)
{
    Bool bResult = TRUE;
    fsl_u08 xStatus;

    // 检查块
    xStatus = FSL_BlankCheck((fsl_u16)u16BlockNum);
    while(xStatus == FSL_BUSY)
    {
        WDTE = 0xACU;
        xStatus = FSL_StatusCheck();
    }

    // 执行错误
    if(xStatus != FSL_OK)
    {
        bResult = FALSE;
    }

    // 返回结果
    return bResult;
}

/*******************************************************************************
  * 函数名：Flash_EraseBlock
  * 功  能：擦除块
  * 参  数：U16 u16BlockNum - 块号
  * 返回值：结果
  * 说  明：无
*******************************************************************************/
#pragma location="FSL_RCD"
Bool Flash_EraseBlock(U16 u16BlockNum)
{
    Bool bResult = TRUE;
    fsl_u08 xStatus;

    // 擦除块
    xStatus = FSL_Erase((fsl_u16)u16BlockNum);
    while(xStatus == FSL_BUSY)
    {
        WDTE = 0xACU;
        xStatus = FSL_StatusCheck();
    }

    // 执行错误
    if(xStatus != FSL_OK)
    {
        bResult = FALSE;
    }

    // 返回结果
    return bResult;
}

/*******************************************************************************
  * 函数名：Flash_WriteWords
  * 功  能：写入字
  * 参  数：U32 u32Addr - 写入地址
  *         U8* pu8Data - 数据指针
  *         U8 u8Count  - 字数
  * 返回值：结果
  * 说  明：1word = 4byte
*******************************************************************************/
#pragma location="FSL_RCD"
Bool Flash_WriteWords(U32 u32Addr, U8* pu8Data, U8 u8Count)
{
    Bool bResult = TRUE;
    fsl_u08 xStatus;
    fsl_write_t xWriteStr;

    // 地址不是4的倍数
    if(u32Addr & 0x03)
    {
        bResult = FALSE;
    }
    // 地址是4的倍数
    else
    {
        // 设置写入参数
        xWriteStr.fsl_data_buffer_p_u08       = (fsl_u08 __near *)pu8Data;
        xWriteStr.fsl_destination_address_u32 = (fsl_u32)u32Addr;
        xWriteStr.fsl_word_count_u08          = (fsl_u08)u8Count;
        // 写入数据
        xStatus = FSL_Write(&xWriteStr);
        while(xStatus == FSL_BUSY)
        {
            WDTE = 0xACU;
            xStatus = FSL_StatusCheck();
        }
        // 执行错误
        if(xStatus != FSL_OK)
        {
            bResult = FALSE;
        }
    }

    // 返回结果
    return bResult;
}

/*******************************************************************************
  * 函数名：Flash_VerifyBlock
  * 功  能：校验块
  * 参  数：U16 u16BlockNum - 块号
  * 返回值：结果
  * 说  明：无
*******************************************************************************/
#pragma location="FSL_RCD"
Bool Flash_VerifyBlock(U16 u16BlockNum)
{
    Bool bResult = TRUE;
    fsl_u08 xStatus;

    // 校验块
    xStatus = FSL_IVerify((fsl_u16)u16BlockNum);
    while(xStatus == FSL_BUSY)
    {
        WDTE = 0xACU;
        xStatus = FSL_StatusCheck();
    }

    // 执行错误
    if(xStatus != FSL_OK)
    {
        bResult = FALSE;
    }

    // 返回结果
    return bResult;
}

/***************************** 文件结束 ***************************************/
